﻿using DevExpress.Utils;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraTreeList;
using DevExpress.XtraTreeList.Columns;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
using Smart.Data.Helper;
using Smart.Utils.Security2;
using Smart.Utils.UI;
using System;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Xml;

namespace Smart.Common
{
    public partial class xfmDatabaseConfig : DevExpress.XtraEditors.XtraForm
    {
        private bool _exit;
        private bool _isCancel = true;
        private int _part;
        private readonly string _serverParameters = (Application.StartupPath + @"\Data.config.xml");
        private const string DefData = "HRMExample";


        public event CancelEventHander Cancel;

        private event CompleteEventHander Complete;

        private event DatabasedEventHander Databased;

        public event DatabaseErrorEventHander DatabaseError;

        public event LoginedEventHander Logined;

        private event ProcessEventHander Process;

        private event StartedEventHander Started;
        public xfmDatabaseConfig()
        {
            InitializeComponent();
        }

        private void xfmDatabaseConfig_Load(object sender, EventArgs e)
        {
            this.cbxServer.Text = Environment.MachineName + @"\Smart";
            this.Started = (StartedEventHander)Delegate.Combine(this.Started, new StartedEventHander(this.xfmLogin_Started));
            this.Complete = (CompleteEventHander)Delegate.Combine(this.Complete, new CompleteEventHander(this.xfmLogin_Complete));
            this.Databased = (DatabasedEventHander)Delegate.Combine(this.Databased, new DatabasedEventHander(this.xfmLogin_Databased));
            this.DatabaseError = (DatabaseErrorEventHander)Delegate.Combine(this.DatabaseError, new DatabaseErrorEventHander(this.xfmLogin_DatabaseError));
            this.ReadCofig();
        }


        private void RaiseCancelEventHander()
        {
            if (this.Cancel != null)
            {
                this.Cancel(this);
            }
        }

        private void RaiseCompleteEventHander(object data)
        {
            if (this.Complete != null)
            {
                this.Complete(this, data);
            }
        }

        private void RaiseDatabasedEventHander(object data)
        {
            if (this.Databased != null)
            {
                this.Databased(this, data);
            }
        }

        private void RaiseDatabaseErrorEventHander(string message)
        {
            if (this.DatabaseError != null)
            {
                this.DatabaseError(this, message);
            }
        }

        private void RaiseLoginedEventHander(string ConnectString)
        {
            if (this.Logined != null)
            {
                this.Logined(this, ConnectString);
            }
        }

        private void RaiseProcessEventHander(string Message)
        {
            if (this.Process != null)
            {
                this.Process(this, Message);
            }
        }

        private void RaiseStartedEventHander()
        {
            if (this.Started != null)
            {
                this.Started(this);
            }
        }

        private void ReadCofig()
        {
            DataTable table = new DataTable("SERVER");
            table.Columns.Add("server");
            table.Columns.Add("auth");
            table.Columns.Add("user");
            table.Columns.Add("pass");
            table.Columns.Add("database");
            table.Columns.Add("ConnectString");
            SqlHelper helper = new SqlHelper();
            FileInfo info = new FileInfo(this._serverParameters);
            if (info.Exists)
            {
                DataSet set = new DataSet();
                set.Tables.Add(table);
                set.ReadXml(this._serverParameters, XmlReadMode.Auto);
                try
                {
                    if (set.Tables[0].Rows.Count > 0)
                    {
                        helper.Server = set.Tables[0].Rows[0]["server"].ToString();
                        helper.Authentication = Convert.ToInt32(set.Tables[0].Rows[0]["auth"]) == 0;
                        helper.UserID = MyEncryption.Decrypt(set.Tables[0].Rows[0]["user"].ToString(), "963147", true);
                        helper.Password = MyEncryption.Decrypt(set.Tables[0].Rows[0]["pass"].ToString(), "963147", true);
                        helper.Database = set.Tables[0].Rows[0]["database"].ToString();
                        helper.ConnectionString = MyEncryption.Decrypt(set.Tables[0].Rows[0]["ConnectString"].ToString(), "963147", true);
                        this.cbxServer.Text = helper.Server;
                        this.teLogin.Text = helper.UserID;
                        this.tePassword.Text = helper.Password;
                        this.cbxDatabase.Text = helper.Database;
                        this.rdgAuthentication.SelectedIndex = helper.Authentication ? 0 : 1;
                        this.ckDataExample.Checked = helper.Database == "HRMExample";
                    }
                }
                catch (Exception exception)
                {
                    XtraMessageBox.Show(exception.Message, "Th\x00f4ng b\x00e1o", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                }
            }
        }

        private void SaveConfig(string server, int auth, string user, string pass, string database, string connecstring)
        {
            try
            {
                DataSet set = new DataSet();
                DataTable table = new DataTable("SERVER");
                table.Columns.Add("server");
                table.Columns.Add("auth");
                table.Columns.Add("user");
                table.Columns.Add("pass");
                table.Columns.Add("database");
                table.Columns.Add("ConnectString");
                table.Rows.Clear();
                table.Rows.Add(new object[] { server, auth, MyEncryption.Encrypt(user, "963147", true), MyEncryption.Encrypt(pass, "963147", true), database, MyEncryption.Encrypt(connecstring, "963147", true) });
                set.Tables.Add(table);
                set.WriteXml(this._serverParameters);
            }
            catch (Exception exception)
            {
                XtraMessageBox.Show(exception.Message, "Th\x00f4ng B\x00e1o", MessageBoxButtons.OK, MessageBoxIcon.Hand);
            }
        }

        private void ShowParameters()
        {
            if (File.Exists(this._serverParameters))
            {
                XmlDocument document = new XmlDocument();
                try
                {
                    document.Load(this._serverParameters);
                    if ((document.DocumentElement != null) && (document.DocumentElement.Name == "Parameters"))
                    {
                        string[] strArray = document.DocumentElement.InnerText.Split(new char[] { ';' });
                        this.cbxServer.Text = strArray[0];
                        this.rdgAuthentication.SelectedIndex = Convert.ToInt32(strArray[1]);
                        this.teLogin.Text = strArray[2];
                        this.tePassword.Text = strArray[3];
                        this.cbxDatabase.Text = strArray[4];
                    }
                }
                catch
                {
                    File.Delete(this._serverParameters);
                }
            }
        }
        private void loadserver()
        {
            this.RaiseStartedEventHander();
            DataTable data = SmoApplication.EnumAvailableSqlServers();
            this.RaiseCompleteEventHander(data);
        }

        public void WriteXml(string str)
        {
            try
            {
                string filename = Application.StartupPath + @"\sqlconfig.xml";
                XmlDocument document = new XmlDocument();
                document.Load(filename);
                ((XmlElement)document.SelectSingleNode("//SQL")).SetAttribute("ConnectionString", str);
                document.Save(filename);
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
            }
        }


        private void CloseForm()
        {
            base.TopMost = false;
            if (this.CorrectConnection(this.GetServerConnectionString()))
            {
                try
                {
                    using (XmlTextWriter writer = new XmlTextWriter(this._serverParameters, Encoding.UTF8))
                    {
                        writer.WriteElementString("Parameters", this.ConnectionStringParameters);
                    }
                }
                catch
                {
                }
            }
        }

        private SqlConnection Connection(string serverConnectionString)
        {
            Cursor current = Cursor.Current;
            Cursor.Current = Cursors.WaitCursor;
            SqlConnection connection = new SqlConnection(serverConnectionString);
            try
            {
                connection.Open();
            }
            catch
            {
                this.RaiseDatabaseErrorEventHander("Kh\x00f4ng thể kết nối được m\x00e1y chủ.");
                return connection;
            }
            finally
            {
                Cursor.Current = current;
            }
            return connection;
        }

        private bool CorrectConnection(string serverConnectionString)
        {
            Cursor current = Cursor.Current;
            Cursor.Current = Cursors.WaitCursor;
            using (SqlConnection connection = new SqlConnection(serverConnectionString))
            {
                try
                {
                    connection.Open();
                    connection.Close();
                }
                catch
                {
                    XtraMessageBox.Show(this, "Kh\x00f4ng thể kết nối với m\x00e1y chủ.", "Th\x00f4ng b\x00e1o", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                    return false;
                }
                finally
                {
                    Cursor.Current = current;
                }
            }
            return true;
        }

        private void DatabaseReload()
        {
            Cursor.Current = Cursors.WaitCursor;
            this.RaiseStartedEventHander();
            DataTable data = new DataTable();
            data.Columns.Add("Database");
            try
            {
                SqlConnection sqlConnection = this.Connection(this.GetServerConnectionString());
                if (sqlConnection.State != ConnectionState.Open)
                {
                    return;
                }
                ServerConnection serverConnection = new ServerConnection(sqlConnection);
                Server server = new Server(serverConnection);
                foreach (Database database in server.Databases)
                {
                    try
                    {
                        if (this._part == 0)
                        {
                            if (database.ExecuteWithResults("select * from SYS_INFO").Tables[0].Rows.Count > 0)
                            {
                                data.Rows.Add(new object[] { database.Name });
                            }
                        }
                        else
                        {
                            data.Rows.Add(new object[] { database.Name });
                        }
                    }
                    catch
                    {
                    }
                }
            }
            catch (Exception exception)
            {
                this.RaiseDatabaseErrorEventHander(exception.Message);
            }
            this.RaiseDatabasedEventHander(data);
        }

        private void Disable(bool disable)
        {
            this.trlServer.Enabled = disable;
            this.cbxServer.Enabled = disable;
            this.rdgAuthentication.Enabled = disable;
            this.cbxDatabase.Enabled = disable;
            this.btnLogin.Enabled = disable;
            this.btnCancel.Enabled = disable;
            this.btnHelp.Enabled = disable;
            this.picRefreshserver.Enabled = disable;
            this.picRefreshdatabase.Enabled = disable;
            this.ckDataExample.Enabled = disable;
        }

        private void DisableSQLServerAuthentication(bool disable)
        {
            this.teLogin.Enabled = !disable;
            this.tePassword.Enabled = !disable;
        }

        private void rdgAuthentication_SelectedIndexChanged(object sender, EventArgs e)
        {
            bool disable = this.rdgAuthentication.SelectedIndex == 0;
            this.DisableSQLServerAuthentication(disable);
        }

        private void rdgAuthentication_KeyDown(object sender, KeyEventArgs e)
        {

        }

        private void tePassword_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == System.Windows.Forms.Keys.Return)
            {
                this.btnLogin_Click(this, null);
            }
        }

        private void cbxServer_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.cbxDatabase.Properties.Items.Clear();
        }

        private void cbxDatabase_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void cbxDatabase_EditValueChanged(object sender, EventArgs e)
        {
            this.ckDataExample.Checked = this.cbxDatabase.Text == "HRMExample";
        }

        private void cbxDatabase_Properties_ButtonClick(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            if ((((string)e.Button.Tag) == "load") && (this.cbxDatabase.Properties.Items.Count == 0))
            {
                new Thread(new ThreadStart(this.DatabaseReload)).Start();
                if (this.cbxDatabase.Properties.Items.Count > 0)
                {
                    this.cbxDatabase.SelectedIndex = -1;
                }
            }
        }

        private void cbxDatabase_Click(object sender, EventArgs e)
        {

        }

        private void trlServer_FocusedNodeChanged(object sender, DevExpress.XtraTreeList.FocusedNodeChangedEventArgs e)
        {
            string str = e.Node.GetValue(this.tlcServer).ToString();
            switch (str)
            {
                case "M\x00e1y Đơn":
                    this.cbxServer.Text = Environment.MachineName + @"\Smart";
                    return;

                case "Mạng Nội Bộ":
                    if (!e.Node.HasChildren)
                    {
                        new Thread(new ThreadStart(this.loadserver)).Start();
                        this.trlServer.ExpandAll();
                    }
                    return;

                case "Mạng Internet":
                    this.cbxServer.Text = "http://";
                    return;
            }
            this.cbxServer.Text = str;
        }

        private void picRefreshdatabase_MouseLeave(object sender, EventArgs e)
        {
            this.picRefreshdatabase.BorderStyle = BorderStyles.NoBorder;
        }

        private void picRefreshdatabase_MouseHover(object sender, EventArgs e)
        {
            this.picRefreshdatabase.BorderStyle = BorderStyles.UltraFlat;
        }

        private void picRefreshdatabase_Click(object sender, EventArgs e)
        {

        }

        private void picRefreshserver_MouseLeave(object sender, EventArgs e)
        {
            this.picRefreshserver.BorderStyle = BorderStyles.NoBorder;
        }

        private void picRefreshserver_MouseHover(object sender, EventArgs e)
        {
            this.picRefreshserver.BorderStyle = BorderStyles.UltraFlat;
        }

        private void ckDataExample_CheckedChanged(object sender, EventArgs e)
        {

            DataTable table = new DataTable("SERVER");
            table.Columns.Add("server");
            table.Columns.Add("auth");
            table.Columns.Add("user");
            table.Columns.Add("pass");
            table.Columns.Add("database");
            table.Columns.Add("ConnectString");
            SqlHelper helper = new SqlHelper();
            FileInfo info = new FileInfo(this._serverParameters);
            if (info.Exists)
            {
                DataSet set = new DataSet();
                set.Tables.Add(table);
                set.ReadXml(this._serverParameters, XmlReadMode.Auto);
                try
                {
                    if (set.Tables[0].Rows.Count > 0)
                    {
                        helper.Server = set.Tables[0].Rows[0]["server"].ToString();
                        helper.Authentication = Convert.ToInt32(set.Tables[0].Rows[0]["auth"]) == 0;
                        helper.UserID = MyEncryption.Decrypt(set.Tables[0].Rows[0]["user"].ToString(), "963147", true);
                        helper.Password = MyEncryption.Decrypt(set.Tables[0].Rows[0]["pass"].ToString(), "963147", true);
                        helper.Database = set.Tables[0].Rows[0]["database"].ToString();
                        helper.ConnectionString = MyEncryption.Decrypt(set.Tables[0].Rows[0]["ConnectString"].ToString(), "963147", true);
                        if (helper.Database == "HRMExample")
                        {
                            if (this.ckDataExample.Checked)
                            {
                                this.cbxDatabase.Text = "HRMExample";
                            }
                            else
                            {
                                this.cbxServer.Text = helper.Server;
                                this.teLogin.Text = helper.UserID;
                                this.tePassword.Text = helper.Password;
                                this.rdgAuthentication.SelectedIndex = helper.Authentication ? 0 : 1;
                                if (this.cbxDatabase.Properties.Items.Count == 0)
                                {
                                    new Thread(new ThreadStart(this.DatabaseReload)).Start();
                                    if (this.cbxDatabase.Properties.Items.Count > 0)
                                    {
                                        this.cbxDatabase.SelectedIndex = -1;
                                    }
                                }
                            }
                        }
                        else if (this.ckDataExample.Checked)
                        {
                            this.cbxDatabase.Text = "HRMExample";
                        }
                        else
                        {
                            this.cbxServer.Text = helper.Server;
                            this.teLogin.Text = helper.UserID;
                            this.tePassword.Text = helper.Password;
                            this.cbxDatabase.Text = helper.Database;
                            this.rdgAuthentication.SelectedIndex = helper.Authentication ? 0 : 1;
                        }
                    }
                }
                catch (Exception exception)
                {
                    XtraMessageBox.Show(exception.Message, "Th\x00f4ng b\x00e1o", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                }
            }
        }

        private void xfmDatabaseConfig_FormClosing(object sender, FormClosingEventArgs e)
        {

        }

        private void btnLogin_Click(object sender, EventArgs e)
        {
            if (this.cbxDatabase.Text != "")
            {
                string dataBaseConnectionString = this.GetDataBaseConnectionString();
                if (this.CorrectConnection(dataBaseConnectionString))
                {
                    if (this._part == 0)
                    {
                        this.SaveConfig(this.cbxServer.Text, this.rdgAuthentication.SelectedIndex, this.teLogin.Text, this.tePassword.Text, this.cbxDatabase.Text, dataBaseConnectionString);
                    }
                    SqlHelper.ConnectString = dataBaseConnectionString;
                    this._isCancel = false;
                    this.RaiseLoginedEventHander(dataBaseConnectionString);
                    base.Close();
                }
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this._isCancel = true;
            base.Close();
        }

        private void btnHelp_Click(object sender, EventArgs e)
        {
            FileInfo info = new FileInfo(Application.StartupPath + @"\QLCSDL.wmv");
            if (info.Exists)
            {
                System.Diagnostics.Process.Start(info.FullName);
            }
        }

        private void xfmLogin_Complete(object sender, object data)
        {
            if (this.trlServer.InvokeRequired)
            {
                CompleteEventHander method = new CompleteEventHander(this.xfmLogin_Complete);
                base.Invoke(method, new object[] { sender, data });
            }
            else
            {
                this.spWait.Visible = false;
                this.spWait.Active = false;
                DataTable table = (DataTable)data;
                if (table.Rows.Count > 0)
                {
                    this.cbxServer.Properties.Items.Clear();
                    this.trlServer.Nodes[1].Nodes.Clear();
                }
                for (int i = 0; i < table.Rows.Count; i++)
                {
                    this.cbxServer.Properties.Items.Add(table.Rows[i]["Name"]);
                    this.trlServer.AppendNode(new object[] { table.Rows[i]["Name"] }, 1, 40, 40, -1);
                }
                this.cbxServer.SelectedIndex = 0;
                Cursor.Current = Cursors.Default;
                this.Disable(true);
            }
        }

        private void xfmLogin_Databased(object sender, object data)
        {
            if (this.trlServer.InvokeRequired)
            {
                DatabasedEventHander method = new DatabasedEventHander(this.xfmLogin_Databased);
                base.Invoke(method, new object[] { sender, data });
            }
            else
            {
                DataTable table = (DataTable)data;
                if (table != null)
                {
                    for (int i = 0; i < table.Rows.Count; i++)
                    {
                        this.cbxDatabase.Properties.Items.Add(table.Rows[i][0]);
                    }
                }
                this.Disable(true);
                this.spWait.Visible = false;
                Cursor.Current = Cursors.Default;
                if (this.cbxDatabase.Properties.Items.Count > 0)
                {
                    this.cbxDatabase.SelectedIndex = -1;
                }
                else
                {
                    XtraMessageBox.Show("Kh\x00f4ng t\x00ecm thấy cơ sở dữ liệu trong m\x00e1y chủ n\x00e0y.", "Cảnh B\x00e1o", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
            }
        }

        private void xfmLogin_DatabaseError(object sender, string message)
        {
            if (this.trlServer.InvokeRequired)
            {
                DatabaseErrorEventHander method = new DatabaseErrorEventHander(this.xfmLogin_DatabaseError);
                base.Invoke(method, new object[] { sender, message });
            }
            else
            {
                XtraMessageBox.Show(this, message, "Th\x00f4ng b\x00e1o", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                this.Disable(true);
                this.spWait.Visible = false;
                Cursor.Current = Cursors.Default;
            }
        }

        private void xfmLogin_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (this._isCancel)
            {
                this.RaiseCancelEventHander();
            }
        }

        private void xfmLogin_Load(object sender, EventArgs e)
        {
        }

        private void xfmLogin_Started(object sender)
        {
            if (this.trlServer.InvokeRequired)
            {
                StartedEventHander method = new StartedEventHander(this.xfmLogin_Started);
                base.Invoke(method, new object[] { sender });
            }
            else
            {
                Cursor.Current = Cursors.WaitCursor;
                this.spWait.Visible = true;
                this.spWait.Active = true;
                this.Disable(false);
            }
        }

        public string ConnectionStringParameters
        {
            get
            {
                return string.Format("{0};{1};{2};{3};{4};{5}", new object[] { this.cbxServer.Text, this.rdgAuthentication.SelectedIndex, this.teLogin.Text, this.tePassword.Text, this.cbxDatabase.Text, this.GetServerConnectionString() });
            }
        }

        public bool IsExit
        {
            get
            {
                return this._exit;
            }
            set
            {
                this._exit = value;
            }
        }

        public string MyServer
        {
            get
            {
                return this.cbxServer.Text;
            }
        }

        public int Part
        {
            get
            {
                return this._part;
            }
            set
            {
                this._part = value;
            }
        }

        public string UserName
        {
            get
            {
                return this.cbxServer.Text;
            }
        }

        public delegate void CancelEventHander(object sender);

        private delegate void CompleteEventHander(object sender, object data);

        private delegate void DatabasedEventHander(object sender, object data);

        public delegate void DatabaseErrorEventHander(object sender, string message);

        public delegate void LoginedEventHander(object sender, string ConnectString);

        private delegate void ProcessEventHander(object sender, string Message);

        private delegate void StartedEventHander(object sender);
    }
}